<?php

// | Copyright (c) 2019~2020 http://jiunidu.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: huanglijun <80792275@qq.com>
// +----------------------------------------------------------------------

namespace service;

use think\facade\Log;
use model\BaseModel;
use think\facade\Config;
use think\Db;
use service\pay\VirtualPay;

class Distribution extends Basemodel
{
    //设置初始分销级别数
    protected $distribution_level = 2;
    //用户表
    protected $user_table = 'user';   
    //用户等级表
    protected $grade_table = 'user_grade';
    //分销表
    protected $distribution_table = 'distribution';       
    //返利表
    protected $distribution_rebate_table = 'distribution_rebate';  
    //余额表
    protected $user_balance_table = 'user_balance';  
    //金币表
    protected $user_coin_table = 'user_coin';  
    //当前用户 
    protected $user_id=0;
    //推荐人用户
    protected $top_user_id=0;
    //当前分销级别
    protected $level=0;
    //满足条件的分销数组
    protected $distribution_array=array();
    //订单汇总表
    protected $core_order_table='core_order';
    //订单汇总产品表
    protected $core_order_product_table='core_order_product';

    public function __construct()
    {
        $this->distribution_level=Config::get("admin.distribution_level");
    }

    /**
     * 获取用户等级价格
     * @param  int         $user_id          用户ID
     * @param  int         $rebate_type      返利的类型 1->商品 2->拼团 3->众筹 4->社区活动
     * @param  int         $foreign_id       外表ID
     * @return float                         返还用户的会员等级对应的自购价格  -1为没有设置，则使用原价格
     */
    public function getGradePrice($user_id=0,$rebate_type=0,$foreign_id=0)
    {
        $grade_price=-1;
        if(empty($user_id)||empty($rebate_type)||empty($foreign_id))
        {
            return  $grade_price=-1;
        }

        //查询当前用户的用户等级
        $user_where=[['user_id','=',$user_id]];
        $user_field=['grade_id'];
        $user_return_data=$this->get_one_data($this->user_table,$user_field,$user_where);
        if(empty($user_return_data['grade_id']))
        {
            return $grade_price;
        }
        //查询是否存在，存在则更新
        $where=[['foreign_id','=',$foreign_id],['grade_id','=',$user_return_data['grade_id']],['rebate_type','=',$rebate_type]];
        $field=['self_buy'];
        $return_data=$this->get_one_data($this->distribution_rebate_table,$field,$where);
        if(!empty($return_data['self_buy']))
        {
            if((float)$return_data['self_buy']>0)
            {
                return (float)$return_data['self_buy'];
            }
        }
        return  $grade_price;
    }

    /**
     * 设定用户分销
     * @param  int         $user_id          用户ID
     * @param  int         $top_user_id      推荐人
     * @return int                            
     */
    public function setDistribution($user_id=0,$top_user_id=0)
    {
        $insert_id=-1;
        //检查数据，如果分享者为自己则取消
        if(empty($user_id)||empty($top_user_id) || (int)$user_id==(int)$top_user_id)
        {
            return  $insert_id=-1;
        }
        //查询当前用户是否存在
        $user_where=[['user_id','=',$user_id],['user_yesno','=',1]];
        $user_field=['grade_id'];
        $user_return_data=$this->get_one_data($this->user_table,$user_field,$user_where);


        //添加上级分销
        $this->user_id=$user_id;
        $this->top_user_id=$top_user_id;
        $this->get_distribution_array();
        // var_dump($this->distribution_array);
        $add_insert_array=array();
        foreach ($this->distribution_array as $key => $value) 
        {

            if($value['user_id']==$value['top_user_id'])
            {
                continue;
            }

            //根据会员等级获取用户锁定的天数
            $top_user_return_data=array();
            $top_user_field=['i.grade_id','lock_fans_day'];
            $top_user_where=[['user_id','=',$value['top_user_id']],['user_yesno','=',1]];
            $join = [
                [$this->user_table.' i','i.grade_id=a.grade_id'],
            ];
            $top_user_return_data=Db::name($this->grade_table)
                                        ->field($top_user_field)
                                        ->where($top_user_where)
                                        ->alias('a')
                                        ->join($join)
                                        ->find();

            $insert_data['user_id']         =   $user_id;
            $insert_data['top_user_id']     =   $value['top_user_id'];
            $insert_data['level']           =   $value['level'];
            $insert_data['lock_day']        =   $top_user_return_data['lock_fans_day'];
            $insert_data['lock_time']       =   time();
            $insert_data['create_time']     =   time();
            //添加分销数据
            $add_insert_array[]=$insert_data;
        }
        //入库处理
        Db::startTrans();
        try
        {
            foreach ($add_insert_array as $key => $value) 
            {
                $insert_id_num=$this->add_data($this->distribution_table,$value); 
            }
            $insert_id=$insert_id_num;
            Db::commit();
        } 
        catch (\Exception $e) 
        {
            Db::rollback();
            $insert_id=-1;
            Log::write("设置分销失败，回滚操作".$e->getMessage(),"error");
        }
        return  $insert_id;    
    }
    /**
     * 商品支付之后，返利锁定的金币、余额
     * 拼团、众筹拼成功后，返利锁定的金币余额
     * 
     * @param  int         $user_id            订单总额
     * @param  int         $order_sum          订单总额
     * @param  int         $rebate_type        返利类型 1->商品 2->拼团 3->众筹 4->社区活动
     * @param  string      $order_id           订单号
     * @return int                            
     */
    public function lock_virtual($user_id=0,$order_sum=0,$rebate_type=0,$order_id='')
    {
        //返回余额、金币的返利数
        $lock_num=['balance'=>0,'coin'=>0];

        //获取用户的所有上级返利的用户ID，在有效期内的：1、上上级断了，则只影响上上级返利 2、上级断了，则取消所有返利
        $top_user_return_data=array();
        $top_user_field=['i.grade_id','top_user_id','lock_day','lock_time','lock_yesno','level','f.user_nickname','f.user_realname'];
        $top_user_where=[['a.user_id','=',$user_id],['i.user_yesno','=',1]];
        $join = [
            [$this->user_table.' i','i.user_id=a.top_user_id'],
            [$this->user_table.' f','f.user_id=a.user_id'],
        ];
        $top_user_return_data=Db::name($this->distribution_table)
        ->field($top_user_field)
        ->where($top_user_where)
        ->alias('a')
        ->join($join)
        ->order('level desc')
        ->select();
        //判断粉丝是否在有效期内
        foreach ($top_user_return_data as $key => $value) 
        {
            $diff_array=timediff((int)$value['lock_time'],time());
            $lock_day=$value['lock_day']- $diff_array['day'];
            if($lock_day<=0)
            {
                //如果为一级上级断了，则取消所有上级返利
                if($value['level']==1)
                {
                    unset($top_user_return_data);
                    break;
                }
                unset($top_user_return_data[$key]);
            }
        } 

        //根据订单号获取商品的ID;
        $foreign_id=$this->get_foreign_id($rebate_type,$order_id);
        // var_dump($foreign_id);
        if(empty($foreign_id))
        {
            return false;
        }

        //根据返利用户级别获取订单返利的%分比，并计算返利金币、余额
        foreach ($top_user_return_data as $key => $value) 
        {
           
            //查询当前用户等级，当前产品的金币、余额返利百分比
            $user_where=[['grade_id','=',$value['grade_id']],['distribution_level','=',$value['level']],
                        ['rebate_type','=',$rebate_type],['foreign_id','=',$foreign_id['product_id']]];
            $user_field=['rebate_sum','rebate_coin'];
            $user_rebate=$this->get_one_data($this->distribution_rebate_table,$user_field,$user_where);

            //余额百分比
            if(!empty($user_rebate['rebate_sum']))
            {
                $lock_num['balance']=bcmul($order_sum,$user_rebate['rebate_sum'],2);
            }
            //金币百分比
            if(!empty($user_rebate['rebate_coin']))
            {
                $lock_num['coin']=bcmul($order_sum,$user_rebate['rebate_coin'],2);
            }
            //返利入库
            $pay_type=0;
       
            $virtual_pay=new VirtualPay();
            if($lock_num['balance']>0)
            {
                $pay_type=1;  
            }
            if($lock_num['coin']>0)
            {
                $pay_type=2;  
            }
            if($lock_num['coin']>0 && $lock_num['balance']>0)
            {
                $pay_type=3;  
            }
            // var_dump($pay_type);
            if((int)$pay_type>0)
            {
                // var_dump();
              $virtual_pay->public_update_user_lockvirtual($value['top_user_id'],0,1,$pay_type,$lock_num['balance'],$lock_num['coin'],1,$order_id,$value['user_nickname']."+".$foreign_id['product_name'].'冻结返利',2);
            }
        }
        return true;

    }
    /**
     * 商品确定收货后，解锁的金币余额  退款、退换则解锁金额金币，但不更新余额金币
     * 拼团、众筹拼失败后，返利解锁金额金币，但不更新余额金币
     * 
     * @param  int         $rebate_type        返利类型 1->商品 2->拼团 3->众筹 4->社区活动
     * @param  string      $order_id           订单号
     * @param  int         $update_type        是否更新账户的余额、金币 1.更新 2 不更新
     * @return int                            
     */
    public function unlock_virtual($rebate_type=0,$order_id='',$update_type=0)
    {

         //读取订单的返利余额列表
          $user_rebate_balance=array();
          $rebate_field=['num','a.user_id','remark'];
          $rebate_where=[['a.balance_type_id','=',6],['table_id','=',$order_id]];
          $join = [
              [$this->user_table.' i','i.user_id=a.user_id'],
          ];
          $user_rebate_balance=Db::name($this->user_balance_table)
          ->field($rebate_field)
          ->where($rebate_where)
          ->alias('a')
          ->join($join)
          ->select(); 

        //读取订单的返利金币列表
        $user_rebate_coin=array();
        $rebate_field_coin=['num','a.user_id','remark'];
        $rebate_where_coin=[['a.coin_type_id','=',11],['table_id','=',$order_id]];
        $join = [
            [$this->user_table.' i','i.user_id=a.user_id'],
        ];
        $user_rebate_coin=Db::name($this->user_coin_table)
        ->field($rebate_field_coin)
        ->where($rebate_where_coin)
        ->alias('a')
        ->join($join)
        ->select(); 


         //解锁返利入库
         $virtual_pay=new VirtualPay();
         //解锁返利的余额
        foreach ($user_rebate_balance as $key => $value) 
        {
            $virtual_pay->public_update_user_lockvirtual($value['user_id'],0,2,1,$value['num'],0,1,$order_id,'解冻'.$value['remark'],$update_type);
        }
        //解锁返利的金币
        foreach ($user_rebate_coin as $key => $value) 
        {
            $virtual_pay->public_update_user_lockvirtual($value['user_id'],0,2,2,0,$value['num'],1,$order_id,'解冻'.$value['remark'],$update_type);
        }
    }
    /**
     * 根据订单，返回相关ID
     * @param int $type            订单类型
     * @param int $order_id        订单号
     * @return int                            
     */
    public function get_foreign_id($type=0,$order_id="")
    {
        $product_return_data=array();
        $product_field=['p.product_id','p.product_name'];
        $product_where=[['c.type','=',$type],['c.order_sn','=',$order_id]];
        $join = [
            [$this->core_order_table.' c','c.order_id=p.order_id'],
        ];
        $product_return_data=Db::name($this->core_order_product_table)
        ->field($product_field)
        ->where($product_where)
        ->alias('p')
        ->join($join)
        ->find(); 
        return $product_return_data;
    }
    /**
     * 返回分销记录数组
     * @return int                            
     */
    public function get_distribution_array()
    {
        $this->level++;
        //分销级别大于系统设定最高结束
        if((int)$this->level>(int)Config::get("api.distribution_level"))
        {
            return false;
        }
        //查询当前用户是否存在分销
        $user_where=[['user_id','=',$this->user_id]];
        $user_field=['top_user_id'];
        $user_return_data=$this->get_one_data($this->distribution_table,$user_field,$user_where);
        //设置上级账户
        $this->top_user_id=empty($user_return_data['top_user_id'])?$this->top_user_id:$user_return_data['top_user_id'];
        //表示当前用户已经存在分销，则返回
        if((int)$this->level==1 && !empty($user_return_data['top_user_id']))
        {
            return false;
        }
        
        //设置分销的数组
        $this->distribution_array[]=array('user_id'=>$this->user_id,'top_user_id'=>$this->top_user_id,'level'=>$this->level);
        $this->user_id=$this->top_user_id;
        $this->get_distribution_array();
    }

    /**
     * @return array    返回会员等级数据
     */
    public function getRebateData()
    {
        $grade_list_data=array();
        $field=['grade_id','grade_name'];
        $grade_list_data=$this->get_page_data($this->grade_table,$field,[],1,20,'grade_num'); //获取数据
        //获取会员等级数据
        $rebate_array=[];
        for($i=0;$i<=$this->distribution_level;$i++)
        {
      
            $rebate_array[$i][0]=$grade_list_data;
        }
        return $rebate_array;
    }

    /**
     * 获取等级返利数据
     * @param  array         $rebate_type      返利的类型 1->商品 2->拼团 3->众筹 4->社区活动
     * @param  array         $foreign_id       外表ID
     * @return array                           
     */
    public function getData($rebate_type=0,$foreign_id=0)
    {
        $data=array();
        $field=['distribution_level','rebate_coin','rebate_sum','self_buy','grade_id','is_rebate','rebate_num'];
        $where=[['rebate_type','=',$rebate_type],['foreign_id','=',$foreign_id]];
        $data = Db::name($this->distribution_rebate_table)->field($field)->where($where)->select();;
        return  $data;
    }
    
    /**
     * 插入或者更新等级返利数据
     * @param  array         $rebate_data      返利的数据
     * @param  array         $rebate_type      返利的类型 1->商品 2->拼团 3->众筹 4->社区活动
     * @param  array         $foreign_id       外表ID
     * @param  array         $foreign_id       模板编号
     * @return array                           返回记录ID,失败为-1
     */
    public function addRebateData($rebate_data=array(),$rebate_type=0,$foreign_id=0,$rebate_num=0)
    {
        $insert_id = -1; 
        if(!is_array($rebate_data)||(int)$rebate_type<=0 || (int)$foreign_id<=0)
        {
            return  $insert_id;
        }

         //启动事务,因为需要处理多张表
         Db::startTrans();
         try
         {
            foreach ($rebate_data as $key => $value) 
            {
                //添加或者更新返利
                if($key>0)
                {
                    $insert_array=array();
                    foreach ($value['balance'] as $key1 => $value1) 
                    {
                        $data['rebate_type']=$rebate_type;
                        $data['grade_id']=$key1;
                        $data['distribution_level']=$key;
                        $data['foreign_id']=$foreign_id;
                        $data['rebate_coin']=$value['coin'][$key1];
                        $data['rebate_sum']=$value1;
                        $data['self_buy']=0;
                        $data['rebate_num']=$rebate_num;
                        if ($rebate_num)
                        {
                            $data['is_rebate']=1;
                        }else
                        {
                            $data['is_rebate']=0;
                        }
                        $insert_array[]= $data;
                    }
                }

                //添加或者更新自购价
                if($key==0)
                {
                    $insert_array=array();
                    foreach ($value as $key1 => $value1) 
                    {
                        $data['rebate_type']=$rebate_type;
                        $data['grade_id']=$key1;
                        $data['distribution_level']=$key;
                        $data['foreign_id']=$foreign_id;
                        $data['rebate_coin']=0;
                        $data['rebate_sum']=0;
                        $data['self_buy']=$value1;
                        $data['rebate_num']=$rebate_num;
                        if ($rebate_num)
                        {
                            $data['is_rebate']=1;
                        }else
                        {
                            $data['is_rebate']=0;
                        }
                        $insert_array[]= $data;
                    }  
                }

                foreach ($insert_array as $key3 => $value3) 
                {
                    //查询是否存在，存在则更新
                    $where=[['distribution_level','=',$value3['distribution_level']],['foreign_id','=',$foreign_id],['grade_id','=',$value3['grade_id']],['rebate_type','=',$rebate_type]];
                    $field=['rebate_id'];
                    $return_data=$this->get_one_data($this->distribution_rebate_table,$field,$where);
                    if(empty($return_data))
                    {
                        $insert_id_num=$this->add_data($this->distribution_rebate_table,$value3); 
                    }
                    else
                    {
                        $where=[['rebate_id','=', $return_data['rebate_id']]];
                        $update_num=Db::name($this->distribution_rebate_table)
                            ->where($where)
                            ->update($value3);
                    }
                }

             }
            Db::commit();
            $insert_id=1;    
        } catch (\Exception $e) 
        {
            Db::rollback();
            $insert_id=-1;
            Log::write("返利，回滚操作".$e->getMessage(),"error");
        }
        return  $insert_id;    
    }
}